﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using STARShell.Core.Interfaces;
using System.ServiceModel;
using Ninject.Core;

namespace STARShell.Core.DefaultRouter.Service
{
    public partial class STARShellRouter : ServiceBase
    {
        private ServiceHost Host { get; set; }
        private ISTARShellRouterService Service { get; set; }
        private IKernel Kernel { get; set; }
        private string[] PreviousArgs { get; set; }
        private object lockObject = new object();

        public STARShellRouter()
        {
            Debug();
            InitializeComponent();
        }

        [Conditional("DEBUG")]
        private void Debug()
        {
            if (!Debugger.IsAttached)
            {
                Debugger.Launch();
            }
        }

        protected override void OnStart(string[] args)
        {
            lock (lockObject)
            {
                PreviousArgs = args;
                IKernel kernel = new StandardKernel(new Modules.DefaultGameModule());
                ISTARShellRouterService ser = kernel.Get<ISTARShellRouterService>();
                ServiceHost host = new ServiceHost(ser);
                Host = host;
                Service = ser;
                Kernel = kernel;
                WireAndStart();
            }
        }

        private void WireAndStart()
        {
            lock (lockObject)
            {
                Host.Faulted += new EventHandler(HandleFaultOnHost);
                Host.Open();
            }
        }

        void HandleFaultOnHost(object sender, EventArgs e)
        {
            lock (lockObject)
            {
                OnStop();
                OnStart(PreviousArgs);
            }
        }

        private void UnwireAndStop()
        {
            lock (lockObject)
            {
                Host.Faulted -= HandleFaultOnHost;
                Host.Close();
            }
        }

        protected override void OnStop()
        {
            lock (lockObject)
            {
                try
                {
                    UnwireAndStop();
                    Kernel.Dispose();
                    Kernel = null;
                    Service = null;
                    Host.Abort();
                }
                catch
                {
                }
            }
        }
    }
}
